// Copyright (C) Kumo inc. and its affiliates.
// Author: Jeff.li lijippy@163.com
// All rights reserved.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.
//


#pragma once

#include <pollux/dwio/common/statistics.h>
#include <pollux/dwio/common/compression/compression.h>

namespace kumo::pollux::parquet {
    /// ColumnChunkMetaDataPtr is a proxy around pointer to thrift::ColumnChunk.
    class ColumnChunkMetaDataPtr {
    public:
        explicit ColumnChunkMetaDataPtr(const void *metadata);

        ~ColumnChunkMetaDataPtr();

        /// Check the presence of ColumnChunk metadata.
        bool hasMetadata() const;

        /// Check the presence of statistics in the ColumnChunk metadata.
        bool hasStatistics() const;

        /// Check the presence of the dictionary page offset in ColumnChunk metadata.
        bool hasDictionaryPageOffset() const;

        /// Return the ColumnChunk statistics.
        std::unique_ptr<dwio::common::ColumnStatistics> getColumnStatistics(
            const TypePtr type,
            int64_t numRows);

        /// Return the Column Metadata Statistics Min Value
        std::string getColumnMetadataStatsMinValue();

        /// Return the Column Metadata Statistics Max Value
        std::string getColumnMetadataStatsMaxValue();

        /// Return the Column Metadata Statistics Null Count
        int64_t getColumnMetadataStatsNullCount();

        /// Number of values.
        int64_t numValues() const;

        /// The data page offset.
        int64_t dataPageOffset() const;

        /// The dictionary page offset.
        /// Must check for its presence using hasDictionaryPageOffset().
        int64_t dictionaryPageOffset() const;

        /// The compression.
        common::CompressionKind compression() const;

        /// Total byte size of all the compressed (and potentially encrypted)
        /// column data in this row group.
        /// This information is optional and may be 0 if omitted.
        int64_t totalCompressedSize() const;

        /// Total byte size of all the uncompressed (and potentially encrypted)
        /// column data in this row group.
        /// This information is optional and may be 0 if omitted.
        int64_t totalUncompressedSize() const;

    private:
        const void *ptr_;
    };

    /// RowGroupMetaDataPtr is a proxy around pointer to thrift::RowGroup.
    class RowGroupMetaDataPtr {
    public:
        explicit RowGroupMetaDataPtr(const void *metadata);

        ~RowGroupMetaDataPtr();

        /// The number of columns in this row group. The order must match the
        /// parent's column ordering.
        int numColumns() const;

        /// Return the ColumnChunkMetaData pointer of the corresponding column index.
        ColumnChunkMetaDataPtr columnChunk(int index) const;

        /// Number of rows in this row group.
        int64_t numRows() const;

        /// Total byte size of all the uncompressed column data in this row
        /// group.
        int64_t totalByteSize() const;

        /// Check the presence of file offset.
        bool hasFileOffset() const;

        /// Byte offset from beginning of file to first page (data or dictionary)
        /// in this row group
        int64_t fileOffset() const;

        /// Check the presence of total compressed size.
        bool hasTotalCompressedSize() const;

        /// Total byte size of all the compressed (and potentially encrypted)
        /// column data in this row group.
        /// This information is optional and may be 0 if omitted.
        int64_t totalCompressedSize() const;

    private:
        const void *ptr_;
    };

    /// FileMetaData is a proxy around pointer to thrift::FileMetaData.
    class FileMetaDataPtr {
    public:
        explicit FileMetaDataPtr(const void *metadata);

        ~FileMetaDataPtr();

        /// The total number of rows.
        int64_t numRows() const;

        /// The number of row groups in the file.
        int numRowGroups() const;

        /// Return the RowGroupMetaData pointer of the corresponding row group index.
        RowGroupMetaDataPtr rowGroup(int index) const;

    private:
        const void *ptr_;
    };
} // namespace kumo::pollux::parquet
